package com.lap.auth.application.menu;

import com.lap.auth.application.menu.assembler.MenuAssembler;
import com.lap.auth.application.menu.command.CreateMenuCmd;
import com.lap.auth.application.menu.command.UpdateMenuCmd;
import com.lap.auth.application.menu.dto.MenuNodeDto;
import com.lap.auth.domain.menu.Menu;
import com.lap.auth.domain.menu.repository.MenuRepository;
import com.lap.auth.domain.menu.service.MenuValidator;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Service
public class MenuAppService {

  private final MenuAssembler menuAssembler;
  private final MenuValidator menuValidator;
  private final MenuRepository menuRepository;

  public List<MenuNodeDto> queryMenuTree() {
    List<Menu> allMenus = menuRepository.findList();
    List<MenuNodeDto> flatList = menuAssembler.toDtoList(allMenus);
    return menuAssembler.convertToTree(flatList);
  }

  public Integer createMenu(CreateMenuCmd cmd) {
    Menu menu = menuAssembler.toDomain(cmd);
    Menu parentMenu = menuValidator.assertMenuExists(menu.getPid());
    parentMenu.canCreateChild();
    return menuRepository.save(menu);
  }

  public void updateMenu(Integer id, UpdateMenuCmd cmd) {
    Menu origin = menuValidator.assertMenuExists(id);
    Menu menu = menuAssembler.toDomain(id, cmd);
    List<Menu> child = menuRepository.findByPid(menu.getId());
    menu.assertCanChangeMenuType(origin.getType(), child);
    menuRepository.save(menu);
  }

  public void deleteMenu(Integer id) {
    Menu menu = menuValidator.assertMenuExists(id);
    List<Menu> child = menuRepository.findByPid(id);
    menu.canDelete(child);
    menuRepository.deleteById(id);
  }
}
